package com.sjzd.weixin.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 *  验证请求签名来源于微信服务器
 */
public class SignatureUtils {

    private static final Logger log = LoggerFactory.getLogger(SignatureUtils.class);

    /**
     * 验证该请求来源于微信
     * @param signature
     * @param timestamp
     * @param nonce
     * @param token
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce, String token) {
        // 将timestamp， nonce, token进行字典排序
        String[] arr = new String[] {timestamp, nonce, token};
        Arrays.sort(arr);
        // 将排序后的字符串进行sha1加密
        StringBuilder sb = new StringBuilder();
        for(String str : arr) {
            sb.append(str);
        }
        String tempStr = sha1(sb.toString());
        // 将加密后的字符串与服务器发来的signature进行比较
        if (tempStr.equals(signature.toUpperCase())) {
            return true;
        }
        return false;
    }

    /**
     *  使用SHA-1算法加密出入字符串
     * @param str
     * @return
     */
    private static String sha1(String str) {
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();
            result = byteArrToHexStr(digest);
        } catch (NoSuchAlgorithmException e) {
            log.error("sha-1加密失败，e : {}", e);
        }
        return result;
    }

    /**
     *  将字节数组转换为十六进制字符串
     */
    private static String byteArrToHexStr(byte[] bytes) {
        String strDigest = "";
        for (int i = 0; i < bytes.length; i++) {
            strDigest += byteToHexStr(bytes[i]);
        }
        return strDigest;
    }


    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }
}
